#!/usr/bin/perl
use strict;
use warnings;
use English;
use POSIX qw/sscanf/;

	if ($#ARGV != 1)
	{
		print "usage: $EXECUTABLE_NAME InputDir OutputDir\n" .
		      "  Where InputDir is directory with unicode two-byte encoding\n" .
	              "  mapping files (see http://unicode.org/Public/MAPPINGS), and\n"  .
	              "  OutputDir is directory where would be written C++ files.\n\n";
		exit(0);
	}


my $DIRH = undef;
opendir($DIRH, $ARGV[0]) || die "$ERRNO: `" . $ARGV[0] . "`";
my @AFiles = grep {/\.[Tt][Xx][Tt]$/ && -f "$ARGV[0]/$_" } readdir($DIRH);
closedir($DIRH);

my %HFwdMap;
my %HFwdOrigNameMap;
my @ARevMap;
for (0..65535) { $ARevMap[$_] = 0; }

print "Generating mapping files....\n";

foreach my $SFile(@AFiles)
{
	my $SEncName = $SFile;
	$SEncName =~s/\.[Tt][Xx][Tt]$//g;
	my $SOrigEncName = $SEncName;
	$SEncName =~tr/-/_/;

	my $FH = undef;
	open($FH, $ARGV[0] . '/' . $SFile) || die "$ERRNO: `$SFile`";

	my @AEncFwdMap;
	while(<$FH>)
	{
		unless(/^#/)
		{
			my ($SFrom, $STo) = split(/\t/);
			if (defined $SFrom && defined $STo)
			{
				if ($STo=~m/^\s+$/) { $STo = '0'; }
				eval("\$SFrom = $SFrom; \$STo = $STo;");
				$AEncFwdMap[$SFrom] = $STo;
				$ARevMap[$STo] = $SFrom;
			}
		}
	}
	$HFwdMap{$SEncName} = \@AEncFwdMap;
	$HFwdOrigNameMap{$SEncName} = $SOrigEncName;

	close($FH);

	print "$SFile...Done\n";
}

my $FH;
open($FH, "+>" . $ARGV[1] . "/UnicodeMapHeader.tcc") || die "$ERRNO: `" . $ARGV[1] . "/UnicodeMapHeader.tcc`";

foreach my $SEncName (keys %HFwdMap)
{
	print $FH sprintf("\t/** Forward map for %s encoding */\n\tstatic UINT_16 sFWD%sMap[256];\n\n", $HFwdOrigNameMap{$SEncName}, $SEncName);
}
close $FH;

open($FH, "+>" . $ARGV[1] . "/UnicodeMaps.tcc") || die "$ERRNO: `" . $ARGV[1] . "/UnicodeMaps.tcc`";
foreach my $SEncName (keys %HFwdMap)
{
	print $FH sprintf("//\n// Forward map for %s encoding\n//\nUINT_16 XMLParser::sFWD%sMap[256] =\n{\n\t", $HFwdOrigNameMap{$SEncName}, $SEncName);
	for(my $NI = 0; $NI < 256; ++ $NI)
	{
		print $FH sprintf("0x%04X", $HFwdMap{$SEncName} -> [$NI]);
		if ($NI != 255)
		{
			print $FH ", ";
			if (($NI + 1) % 16 == 0) { print $FH "\n\t"; }
		}

	}
	print $FH "\n};\n\n";
}
close $FH;

open($FH, "+>" . $ARGV[1] . "/UnicodeMapChoose.tcc") || die "$ERRNO: `" . $ARGV[1] . "/UnicodeMapChoose.tcc`";
my $BFirst = 1;
foreach my $SEncName (keys %HFwdMap)
{
	print $FH sprintf("\t// Converter for %s encoding\n", $HFwdOrigNameMap{$SEncName});
	if ($BFirst == 0) { print $FH sprintf("\telse if (strcasecmp(%20s, sEncoding) == 0) { pConverter = %20sMap[0]; }\n", '"' . $HFwdOrigNameMap{$SEncName} . '"', '&sFWD' . $SEncName); }
	else
	{
		$BFirst = 0;
		print $FH sprintf("\tif      (strcasecmp(%20s, sEncoding) == 0) { pConverter = %20sMap[0]; }\n", '"' . $HFwdOrigNameMap{$SEncName} . '"', '&sFWD' . $SEncName);
	}
}

close $FH;
1;
